刚工作的时候,看了王垠的一篇《编辑器之神和神之编辑器》,便落入了使用vim的深坑。工作了那么多年发现每个一段时间重新看vim东西总能学到新的知识,最近快速读完了《Practical Vim》,在这里把一些以前没注意的小技巧再重新整理一下。
normal mode
R进入逐字替换- 用
f{char}搜索某个字符(比如c),按;可以跳到下一个c位置,按,跳到上一个c - 使用相对行号时,如何删除当前行开始向下数3行的内容?
d3j q/查看使用/搜索过的历史命令q:查看 ex 命令历史m{char}标记位置,`{char}调整到标记位置,其中{char}用小写字母是文件内标记,用大写字母是全局标记(可以在文件之间跳转)- 0(数字0)是复制专用寄存器,只有y命令会覆盖它,使用y命令后,”0p可以黏贴寄存器内容。覆盖无名寄存器的操作(x,c,d等)不会覆盖0寄存器
insert mode
<C-r>{register}直接输出寄存器的值,比如<C-r>a是输出a寄存器内容<C-r>=6*35<CR>使用表达式寄存器=,计算6*35的值并输出
virtual mode
v高亮选择文本,gv重选上次高亮选区- 高亮选中文本后,按
o可以将光标在高亮文本起始末尾跳转,方便调整高亮文本
Ex command mode
[range] m {address}把[range] 范围的文本移动到{address}[range] t {address}把[range] 范围的文本复制到{address}<C-r>{register}在命令行黏贴寄存器内容[range] normal {command} 使用命令行执行普通模式命令,如% normal A;会在所有行后面追加字符;- 重复上一次执行的Ex 命令,使用
@: <C-d>显示可用命令列表,Tab补全命令<C-r><C-w>插入当前光标下的单词到编辑的command中
[range] 范围语法支持:
| 符号 | 地址 |
|---|---|
| 1 | 文本第一行 |
| $ | 文本的最后一行 |
| 0 | 虚拟行,位于文本第一行上方 |
| . | 光标所在行 |
| ‘m | 位置标记m所在行 |
| ‘< | 高亮选区的起始行 |
| ‘> | 高亮选区的结束行 |
| % | 整个文件 |
- 允许使用
+{number},-{number}对[range]进行偏移 - [range] 也支持使用模式匹配
Macro (宏)
录制宏:
q{register}开启录制- 录入宏的内容
q结束录制
调用宏:@{register}
批量调用: n@{register} ,这里n是执行宏的次数
向录制好的宏追加内容: 用 q{register大写} 开始录制,录制后的内容会追加到原来的宏后面。比如原来用 qa 录制了 dwi 操作,想要再后面加j,可以:
- 用
qA开启宏a的追加 - 录制
j - 按
q结束录制 - 此时
@a执行的操作就是dwij
编辑宏:
宏用的寄存器和复制黏贴的寄存器是一样的,需要编辑好录制的宏,可以先将寄存器输出,编辑后复制到寄存器中,继续用@{register}执行宏。比如原来寄存器a录制的宏是dwij,现在想要改成dwi2j,可以:
- 在normal mode下,”ap 黏贴出宏内容 dwij
- 将内容改成 dwi2j
- 选中文本,y”a 覆盖寄存器a内容
- 再执行@a,操作就是 dwi2j了
Pattern 模式匹配
vim 的 search(搜索),substitute(替换)命令都支持Pattern,也就是正则表达式匹配
默认情况下,/ 搜索模式的正则表达式,正则表达式的元字符 .*()等,都需要加\转义,也就是在默认情况下/.*搜索的是 .*字符串,而不是任意个字符
magic:
在搜索表达式前加\m使用magic功能,除了 $.*^之外的元字符要加反斜杠,如\m.*搜索的就是任意字符,若不是.*字符串
very magic:
在搜索表达式前\v使用very magic 功能,正则表达式任何元字符都不用加\,如:/\v(a.c){3}$ 就是查找行尾三个字符是a{char}c的表表达式(如abc,acc,aec)。
强制关闭magic:
如果已经set magic,要在搜索表达式里强制不用magic,就在前面加\V,比如已经开启了set magic,使用 /\V.*搜索的是.*字符串。
单词界定:
在very magic 模式下,使用<word>可以以单词为界匹配字符,而不会匹配到其他内容。比如目前有个文本:1
2
3
4abc aa
abcdedf
1234
123abc
用 /\v<abc>搜索时,只有第一行 abc 匹配,123abc不会匹配。
模式匹配边界:
一个匹配的边界通常对应于一个模式的起始与结尾。但我们可以使用元字符 \zs 与 \ze对匹配进行裁剪,使其成为这个完整模式的一个子集(参见 :h /\zs ) 。元 字符 \zs标志着一个匹配的起始,而元字符\ze则用来界定匹配的结束。将二者相结合,我们可以定义一个特殊的模式,它们可以让我们定义一个模式匹配一个较大的文本范围,然后再收窄匹配范围。与单词定界符类似,\zs与\ze 均为零宽度元字符。
vim中模式的特殊元字符 ,\zs 与\ze关键字示例:
必须转义的情况:
- 正向查找时,
/必须转义。 - 反向查找时,
?必须转义。 - 每次都要转义
\。
查找&替换
显示当前查找关键词个数: :%s///gn
将光标定位到匹配结果词尾:/lang/e
重用上次查找的模式:%s/\va.c/123/g
等价于以下两个命令1
2/\v.c
%s//123/g
global 命令
:global命令的广义形式如下所示::g/{pattern}/[range][cmd]:g/{re}/{cmd} 在匹配的行上执行命令,如 :g/re/d ,删除包含re字符的行:v/{re}/{cmd} 在非匹配的行上执行命令 如 :v/re/d ,删除不包含re字符的行